Topic: 開放資料 - 水庫CTSI卡爾森指數-資料視覺化¶
File: 18_water_ctsi_visualization.ipynb
Author: Ming-Chang Lee
Date: 2025.06.16
Data source: https://data.gov.tw/dataset/6345
References:
https://github.com/rwepa/python_data_scientist
參考 RWEPA | Python AQI 空氣品質指標資料分析:
https://rwepa.blogspot.com/2025/03/python-aqi-application.html
🌸YouTube (包括中文字幕):https://youtu.be/0UJbhVWDuI4
Jupyter notebook下載: https://github.com/rwepa/python_data_scientist/blob/main/tutorial_air_quality_index/tutorial_air_quality_index.ipynb
大綱¶
1.商業理解
2.資料理解
2.1 模組與資料匯入
2.2 資料摘要
2.3 探索性資料分析(Exploratory Data Analysis, EDA)
2.4 資料視覺化
3.資料準備
4.建立模型
5.模型評估與測試
6.佈署應用與結論
參考文獻
1.商業理解¶
研究目的: 探討水庫CTSI卡爾森指數資料並進行資料視覺化分析.
資料來源: 政府資料開放平台-水庫水質監測資料
檔案名稱: wqx_p_03.csv
資料筆數: 1000
欄位數量為19個:
| 欄位名稱 | 中文說明 |
|---|---|
| 測站代碼 | siteid |
| 測站名稱 | sitename |
| 測站英文名稱 | siteengname |
| 水庫名稱 | damname |
| 縣市 | county |
| 鄉鎮市區 | township |
| twd97經度 | twd97lon |
| twd97緯度 | twd97lat |
| twd97二度分帶x | twd97tm2x |
| twd97二度分帶y | twd97tm2y |
| 採樣日期 | sampledate |
| 採樣水層 | samplelayer |
| 採樣深度 | sampledepth |
| 測項名稱 | itemname |
| 測項英文名稱 | itemengname |
| 測項英文簡稱 | itemengabbreviation |
| 監測值 | itemvalue |
| 測項單位 | itemunit |
| 備註 | note |
欄位包括地理變數等六大類別:
- 背景變數4個: 測站代碼、測站名稱、測站英文名稱、水庫名稱
- 地理變數6個: 縣市、鄉鎮市區、twd97經度、twd97緯度、twd97二度分帶x、twd97二度分帶y
- 採樣變數2個: 採樣水層、採樣深度
- 水質變數5個: 測項名稱、測項英文名稱、測項英文簡稱、監測值、測項單位
- 日期時間變數1個: 採樣日期
- 其他變數1個: 備註
優養化(Eutrophication):
- 水體中氮、磷等植物營養物質含量過高引起藻類迅速繁殖,產生藻華現象的過程。
- 其間由於釋放藻毒素以及增加水中有機質含量,致使水體溶氧量下降,造成水資源利用時的困擾與水體生態平衡的破壞。
- ㄧ般水體依優養化程度可概分為三大類(1).貧養性 (2)普養性 (3).優養性。
- 參考資料: https://wq.moenv.gov.tw/EWQP/zh/Encyclopedia/NounDefinition/Pedia_01.aspx
卡爾森指數(Carlson Trophic State Index, CTSI or Carlson's TSI):
一般可以使用卡爾森指數(Carlson, 1977)做為衡量水體優養化現象基準。
考慮 $TP$ = 總磷濃度(μg/L)、$Chl-a$ = 葉綠素a濃度(μg/L)、$SD$ = 透明度(m),則 $CTSI = \frac{TSI(TP) + TSI(Chl-a) + TSI(SD)}{3}$,其中
- $TSI (TP) = 14.42 \times ln{TP} + 4.15$
- $TSI (Chl-a) = 9.81 \times ln{Chl-a} + 30.6$
- $TSI (SD) = 60 - 14.41 \times ln{SD}$
卡爾森指數優養程度表:
| 卡爾森指數 | 優養程度 |
|---|---|
| CTSI < 40 | 貧養 |
| 40 ≦ CTSI ≦ 50 | 普養 |
| CTSI > 50 | 優養 |
2.資料理解¶
資料理解包括以下主題, 其中模組與資料匯入及資料摘要為必需主題:
- 模組與資料匯入【必要項目】
- 資料摘要【必要項目】
- 探索性資料分析
- 資料視覺化
- 資料清理
- 資料合併
- 特徵選擇
- 資料轉換
本研究使用 Python 程式語言(Python, 2024)並參考RWEPA網站(Lee, 2024)與Ashouri 等人(2023).
- 安裝 folium 模組: pip install folium

2.1 模組與資料匯入¶
# 模組匯入
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import pyplot
import seaborn as sns
from pandas.plotting import scatter_matrix
import plotly.express as px
import plotly.graph_objects as go
# 匯入地圖模組, 記得先安裝 pip install folium
import folium
# 設定中文字型
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # For Windows
# matplotlib.rcParams['font.sans-serif'] = ['Noto Serif CJK JP'] # For Ubuntu
matplotlib.rcParams['axes.unicode_minus'] = False
# 匯入資料集
urls = 'wqx_p_03.csv'
df = pd.read_csv(urls)
# 顯示資料
df
# 測站名稱有29個
# 每筆記錄有25筆資料列(葉綠素a ~ 卡爾森指數)
# 每筆記錄包括一個以上 sampledepth = {0.5, 3.2, 7.6, ...}
# 湖山水庫二的第1筆資料為第 0列 ~ 第24列, sampledate = 2025/2/4 09:45:00 AM
# 湖山水庫二的第2筆資料為第25列 ~ 第24列, sampledate = 2025/2/4 09:45:00 AM
| siteid | sitename | siteengname | damname | county | township | twd97lon | twd97lat | twd97tm2x | twd97tm2y | sampledate | samplelayer | sampledepth | itemname | itemengname | itemengabbreviation | itemvalue | itemunit | note | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2212 | 湖山水庫二 | NaN | 湖山水庫 | 雲林縣 | NaN | 120.630278 | 23.679167 | 212291.03 | 2619541.36 | 2025-02-04 09:45:00 | 底水 | 7.6 | 葉綠素a | Chlorophyl-A | Chl_a | 3.2 | μg/L | NaN |
| 1 | 2212 | 湖山水庫二 | NaN | 湖山水庫 | 雲林縣 | NaN | 120.630278 | 23.679167 | 212291.03 | 2619541.36 | 2025-02-04 09:45:00 | 底水 | 7.6 | 總磷 | Total-Phosphate | TP | 0.020 | mg/L | NaN |
| 2 | 2212 | 湖山水庫二 | NaN | 湖山水庫 | 雲林縣 | NaN | 120.630278 | 23.679167 | 212291.03 | 2619541.36 | 2025-02-04 09:45:00 | 底水 | 7.6 | 正磷酸鹽 | PO4-P | PO4 | - | mg/L | NaN |
| 3 | 2212 | 湖山水庫二 | NaN | 湖山水庫 | 雲林縣 | NaN | 120.630278 | 23.679167 | 212291.03 | 2619541.36 | 2025-02-04 09:45:00 | 底水 | 7.6 | 溶氧飽和度 | Dissolved Oxygen Saturation | DOS | 92.8 | % | NaN |
| 4 | 2212 | 湖山水庫二 | NaN | 湖山水庫 | 雲林縣 | NaN | 120.630278 | 23.679167 | 212291.03 | 2619541.36 | 2025-02-04 09:45:00 | 底水 | 7.6 | 溶氧(滴定法) | Dissolved Oxygen | DO2 | - | mg/L | NaN |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 995 | 2177 | 鏡面水庫二 | Ching-Mien Reservoir II | 鏡面水庫 | 臺南市 | NaN | 120.488463 | 23.058074 | 197583.15 | 2550805.52 | 2025-02-10 14:14:54 | 表水 | 0.5 | 濁度 | Turbidity | TB | 6.6 | NTU | NaN |
| 996 | 2177 | 鏡面水庫二 | Ching-Mien Reservoir II | 鏡面水庫 | 臺南市 | NaN | 120.488463 | 23.058074 | 197583.15 | 2550805.52 | 2025-02-10 14:14:54 | 表水 | 0.5 | 酸鹼值 | pH | pH | 7.92 | NaN | |
| 997 | 2177 | 鏡面水庫二 | Ching-Mien Reservoir II | 鏡面水庫 | 臺南市 | NaN | 120.488463 | 23.058074 | 197583.15 | 2550805.52 | 2025-02-10 14:14:54 | 表水 | 0.5 | 透明度 | Transparency | SD | 0.5 | m | NaN |
| 998 | 2177 | 鏡面水庫二 | Ching-Mien Reservoir II | 鏡面水庫 | 臺南市 | NaN | 120.488463 | 23.058074 | 197583.15 | 2550805.52 | 2025-02-10 14:14:54 | 表水 | 0.5 | 水溫 | Water Temperature | WT | 21.5 | ℃ | NaN |
| 999 | 2177 | 鏡面水庫二 | Ching-Mien Reservoir II | 鏡面水庫 | 臺南市 | NaN | 120.488463 | 23.058074 | 197583.15 | 2550805.52 | 2025-02-10 14:14:54 | 表水 | 0.5 | 卡爾森指數 | Carlson Trophic State Index | CTSI | 59 | NaN | NaN |
1000 rows × 19 columns
2.2 資料摘要¶
# 資料維度
df.shape # (1000, 19)
(1000, 19)
# 欄位名稱
df.columns
Index(['siteid', 'sitename', 'siteengname', 'damname', 'county', 'township',
'twd97lon', 'twd97lat', 'twd97tm2x', 'twd97tm2y', 'sampledate',
'samplelayer', 'sampledepth', 'itemname', 'itemengname',
'itemengabbreviation', 'itemvalue', 'itemunit', 'note'],
dtype='object')
# 資料型態
# 變數包括 int64(整數)、float64(實數)、object(字串)
# itemvalue 為 object(字串)
df.dtypes
siteid int64 sitename object siteengname object damname object county object township float64 twd97lon float64 twd97lat float64 twd97tm2x float64 twd97tm2y float64 sampledate object samplelayer object sampledepth float64 itemname object itemengname object itemengabbreviation object itemvalue object itemunit object note float64 dtype: object
# 採樣日期(sampledate) 匯入資料為 object (字串), 轉換為日期時間.
df['sampledate'] = pd.to_datetime(df['sampledate'])
df['sampledate']
0 2025-02-04 09:45:00
1 2025-02-04 09:45:00
2 2025-02-04 09:45:00
3 2025-02-04 09:45:00
4 2025-02-04 09:45:00
...
995 2025-02-10 14:14:54
996 2025-02-10 14:14:54
997 2025-02-10 14:14:54
998 2025-02-10 14:14:54
999 2025-02-10 14:14:54
Name: sampledate, Length: 1000, dtype: datetime64[ns]
# 資料摘要
df_describe = df.describe(include='all')
df_describe
| siteid | sitename | siteengname | damname | county | township | twd97lon | twd97lat | twd97tm2x | twd97tm2y | sampledate | samplelayer | sampledepth | itemname | itemengname | itemengabbreviation | itemvalue | itemunit | note | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 1000.000000 | 1000 | 875 | 1000 | 1000 | 0.0 | 1000.000000 | 1000.000000 | 1000.000000 | 1.000000e+03 | 1000 | 1000 | 975.000000 | 1000 | 1000 | 1000 | 1000 | 960 | 0.0 |
| unique | NaN | 29 | 27 | 18 | 9 | NaN | NaN | NaN | NaN | NaN | NaN | 3 | NaN | 25 | 24 | 25 | 393 | 8 | NaN |
| top | NaN | 湖山水庫一 | Feng-Shan Reservoir IV | 鳳山水庫 | 高雄市 | NaN | NaN | NaN | NaN | NaN | NaN | 表水 | NaN | 葉綠素a | Dissolved Oxygen | Chl_a | - | mg/L | NaN |
| freq | NaN | 75 | 75 | 150 | 275 | NaN | NaN | NaN | NaN | NaN | NaN | 725 | NaN | 40 | 80 | 40 | 377 | 600 | NaN |
| mean | 2192.325000 | NaN | NaN | NaN | NaN | NaN | 120.346520 | 23.164780 | 223954.940923 | 2.562615e+06 | 2025-02-11 15:09:39.975000064 | NaN | 5.030769 | NaN | NaN | NaN | NaN | NaN | NaN |
| min | 2177.000000 | NaN | NaN | NaN | NaN | NaN | 118.381116 | 22.133792 | 182975.640000 | 2.448387e+06 | 2025-02-04 09:45:00 | NaN | 0.500000 | NaN | NaN | NaN | NaN | NaN | NaN |
| 25% | 2183.750000 | NaN | NaN | NaN | NaN | NaN | 120.351979 | 22.538902 | 187263.195000 | 2.493354e+06 | 2025-02-04 11:14:46 | NaN | 0.500000 | NaN | NaN | NaN | NaN | NaN | NaN |
| 50% | 2190.000000 | NaN | NaN | NaN | NaN | NaN | 120.514905 | 23.097123 | 211810.820000 | 2.555110e+06 | 2025-02-10 11:39:59 | NaN | 0.500000 | NaN | NaN | NaN | NaN | NaN | NaN |
| 75% | 2201.250000 | NaN | NaN | NaN | NaN | NaN | 120.668030 | 23.679167 | 232767.750000 | 2.619541e+06 | 2025-02-13 11:52:39 | NaN | 7.600000 | NaN | NaN | NaN | NaN | NaN | NaN |
| max | 2212.000000 | NaN | NaN | NaN | NaN | NaN | 121.302083 | 24.806722 | 313893.660000 | 2.744404e+06 | 2025-02-26 10:32:06 | NaN | 33.800000 | NaN | NaN | NaN | NaN | NaN | NaN |
| std | 10.688012 | NaN | NaN | NaN | NaN | NaN | 0.626843 | 0.773537 | 41767.667180 | 8.565253e+04 | NaN | NaN | 8.884444 | NaN | NaN | NaN | NaN | NaN | NaN |
# 篩選經緯度資料
df_location = df[['sitename', 'twd97lon', 'twd97lat']]
df_location = df_location.drop_duplicates()
df_location.shape
(29, 3)
df_location
| sitename | twd97lon | twd97lat | |
|---|---|---|---|
| 0 | 湖山水庫二 | 120.630278 | 23.679167 |
| 50 | 湖山水庫一 | 120.625556 | 23.684083 |
| 125 | 蘭湖水庫 | 118.381116 | 24.451954 |
| 150 | 金湖水庫 | 118.458370 | 24.434472 |
| 175 | 寶二水庫一 | 121.044444 | 24.719495 |
| 200 | 石門水庫六 | 121.302083 | 24.806722 |
| 225 | 大埔水庫 | 120.983752 | 24.675913 |
| 250 | 德基水庫五 | 121.247684 | 24.270084 |
| 275 | 七美水庫 | 119.434562 | 23.211729 |
| 300 | 小池水庫 | 119.509307 | 23.610886 |
| 325 | 西安水庫 | 119.497236 | 23.364550 |
| 350 | 東衛水庫 | 119.597683 | 23.567763 |
| 375 | 興仁水庫 | 119.606836 | 23.549442 |
| 400 | 成功水庫 | 119.625964 | 23.577479 |
| 425 | 牡丹水庫三 | 120.782318 | 22.147105 |
| 475 | 牡丹水庫二 | 120.782567 | 22.140403 |
| 525 | 牡丹水庫一 | 120.781288 | 22.133792 |
| 575 | 鳳山水庫四 | 120.389622 | 22.535145 |
| 650 | 鳳山水庫三 | 120.388483 | 22.538672 |
| 675 | 鳳山水庫二 | 120.390094 | 22.538978 |
| 700 | 鳳山水庫一 | 120.392360 | 22.540565 |
| 725 | 澄清湖水庫四 | 120.350500 | 22.663972 |
| 750 | 澄清湖水庫三 | 120.347806 | 22.661806 |
| 775 | 澄清湖水庫二 | 120.352472 | 22.660361 |
| 825 | 澄清湖水庫一 | 120.354556 | 22.654472 |
| 850 | 南化水庫三 | 120.564178 | 23.126354 |
| 875 | 南化水庫二 | 120.554626 | 23.106803 |
| 925 | 南化水庫一 | 120.541347 | 23.087443 |
| 975 | 鏡面水庫二 | 120.488463 | 23.058074 |
# 資料篩選: sampledepth = 0.5
df_ctsi = df.loc[df['sampledepth'] == 0.5, ['sitename', 'itemname', 'itemvalue']]
df_ctsi # 700*3
| sitename | itemname | itemvalue | |
|---|---|---|---|
| 25 | 湖山水庫二 | 葉綠素a | 3.3 |
| 26 | 湖山水庫二 | 總磷 | 0.019 |
| 27 | 湖山水庫二 | 正磷酸鹽 | - |
| 28 | 湖山水庫二 | 溶氧飽和度 | 89.4 |
| 29 | 湖山水庫二 | 溶氧(滴定法) | - |
| ... | ... | ... | ... |
| 995 | 鏡面水庫二 | 濁度 | 6.6 |
| 996 | 鏡面水庫二 | 酸鹼值 | 7.92 |
| 997 | 鏡面水庫二 | 透明度 | 0.5 |
| 998 | 鏡面水庫二 | 水溫 | 21.5 |
| 999 | 鏡面水庫二 | 卡爾森指數 | 59 |
700 rows × 3 columns
# 篩選資料, 考慮 temname = {葉綠素a, 總磷, 透明度, 卡爾森指數}
# 方法1
# df.loc[(df['欄位1'] > 30) & (df['欄位2'] == 'A'), ['欄位1', '欄位2', '欄位3']]
# df.loc[(df['欄位1'] > 30) | (df['欄位2'] == 'A'), ['欄位1', '欄位2', '欄位3']]
mydf = df_ctsi.loc[(df_ctsi['itemname'] == '葉綠素a') | (df_ctsi['itemname'] == '總磷') | (df_ctsi['itemname'] == '透明度') | (df_ctsi['itemname'] == '卡爾森指數'),]
mydf # 112*3
| sitename | itemname | itemvalue | |
|---|---|---|---|
| 25 | 湖山水庫二 | 葉綠素a | 3.3 |
| 26 | 湖山水庫二 | 總磷 | 0.019 |
| 47 | 湖山水庫二 | 透明度 | 0.6 |
| 49 | 湖山水庫二 | 卡爾森指數 | 52 |
| 100 | 湖山水庫一 | 葉綠素a | 2.7 |
| ... | ... | ... | ... |
| 974 | 南化水庫一 | 卡爾森指數 | 41 |
| 975 | 鏡面水庫二 | 葉綠素a | 6.6 |
| 976 | 鏡面水庫二 | 總磷 | 0.039 |
| 997 | 鏡面水庫二 | 透明度 | 0.5 |
| 999 | 鏡面水庫二 | 卡爾森指數 | 59 |
112 rows × 3 columns
# 方法2
# df.query('欄位1 > 30 & 欄位2 == "A"')[['欄位1', '欄位2', '欄位3']]
# df.query('欄位1 > 30 | 欄位2 == "A"')[['欄位1', '欄位2', '欄位3']]
# same as the above
mydf1 = df_ctsi.query('itemname == "葉綠素a" | itemname == "總磷" | itemname == "透明度" | itemname == "卡爾森指數"')
mydf1
| sitename | itemname | itemvalue | |
|---|---|---|---|
| 25 | 湖山水庫二 | 葉綠素a | 3.3 |
| 26 | 湖山水庫二 | 總磷 | 0.019 |
| 47 | 湖山水庫二 | 透明度 | 0.6 |
| 49 | 湖山水庫二 | 卡爾森指數 | 52 |
| 100 | 湖山水庫一 | 葉綠素a | 2.7 |
| ... | ... | ... | ... |
| 974 | 南化水庫一 | 卡爾森指數 | 41 |
| 975 | 鏡面水庫二 | 葉綠素a | 6.6 |
| 976 | 鏡面水庫二 | 總磷 | 0.039 |
| 997 | 鏡面水庫二 | 透明度 | 0.5 |
| 999 | 鏡面水庫二 | 卡爾森指數 | 59 |
112 rows × 3 columns
# 長寬資料轉換
# 使用 pandas.pivot --> long data to wide data
df_ctsi = mydf1.pivot(index='sitename',
columns='itemname',
values='itemvalue')
df_ctsi.reset_index(inplace=True)
df_ctsi
| itemname | sitename | 卡爾森指數 | 總磷 | 葉綠素a | 透明度 |
|---|---|---|---|---|---|
| 0 | 七美水庫 | 60 | 0.051 | 16.4 | 0.9 |
| 1 | 南化水庫一 | 41 | 0.009 | 2.0 | 2.1 |
| 2 | 南化水庫三 | 48 | 0.014 | 2.7 | 0.9 |
| 3 | 南化水庫二 | 45 | 0.010 | 2.5 | 1.2 |
| 4 | 寶二水庫一 | 57 | 0.085 | 8.8 | 1.8 |
| 5 | 小池水庫 | 59 | 0.037 | 8.8 | 0.5 |
| 6 | 德基水庫五 | 56 | 0.026 | 10.3 | 0.8 |
| 7 | 成功水庫 | 71 | 0.061 | 81.1 | 0.3 |
| 8 | 東衛水庫 | 72 | 0.078 | 75.7 | 0.3 |
| 9 | 湖山水庫一 | 49 | 0.022 | 2.7 | 1.2 |
| 10 | 湖山水庫二 | 52 | 0.019 | 3.3 | 0.6 |
| 11 | 澄清湖水庫一 | 58 | 0.048 | 3.4 | 0.5 |
| 12 | 澄清湖水庫三 | 52 | 0.027 | 3.9 | 1.0 |
| 13 | 澄清湖水庫二 | 52 | 0.028 | 4.7 | 1.1 |
| 14 | 澄清湖水庫四 | 63 | 0.048 | 31.7 | 0.7 |
| 15 | 牡丹水庫一 | 49 | 0.016 | 6.1 | 1.6 |
| 16 | 牡丹水庫三 | 50 | 0.021 | 4.5 | 1.4 |
| 17 | 牡丹水庫二 | 48 | 0.015 | 5.5 | 1.6 |
| 18 | 石門水庫六 | 56 | 0.088 | 2.5 | 1.0 |
| 19 | 興仁水庫 | 74 | 0.078 | 111 | 0.3 |
| 20 | 蘭湖水庫 | 77 | 0.086 | 127 | 0.2 |
| 21 | 西安水庫 | 45 | 0.016 | 2.7 | 1.9 |
| 22 | 金湖水庫 | 66 | 0.070 | 29.7 | 0.6 |
| 23 | 鏡面水庫二 | 59 | 0.039 | 6.6 | 0.5 |
| 24 | 鳳山水庫一 | 78 | 0.816 | 20.4 | 0.4 |
| 25 | 鳳山水庫三 | 80 | 0.763 | 36.4 | 0.4 |
| 26 | 鳳山水庫二 | 80 | 0.788 | 36.3 | 0.4 |
| 27 | 鳳山水庫四 | 81 | 0.659 | 86.7 | 0.5 |
df_ctsi.index
RangeIndex(start=0, stop=28, step=1)
df_ctsi.dtypes
itemname sitename object 卡爾森指數 object 總磷 object 葉綠素a object 透明度 object dtype: object
for col in df_ctsi.columns:
if col not in ['itemname', 'sitename']:
df_ctsi[col] = pd.to_numeric(df_ctsi[col], errors='coerce')
df_ctsi.dtypes
itemname sitename object 卡爾森指數 int64 總磷 float64 葉綠素a float64 透明度 float64 dtype: object
df_ctsi.shape # 28*5
(28, 5)
fig = px.scatter(df_ctsi, x='卡爾森指數', y='總磷')
fig.update_layout(title_text='班級-168-李明昌', title_x=0.5)
# 資料摘要
# aqi 最小值為 16.00, 最大值為 123.00, 平均值為 45.58, 中位數為 34.50
pd.set_option('display.precision', 2)
df_ctsi.describe(include='all')
| itemname | sitename | 卡爾森指數 | 總磷 | 葉綠素a | 透明度 |
|---|---|---|---|---|---|
| count | 28 | 28.00 | 2.80e+01 | 28.00 | 28.00 |
| unique | 28 | NaN | NaN | NaN | NaN |
| top | 七美水庫 | NaN | NaN | NaN | NaN |
| freq | 1 | NaN | NaN | NaN | NaN |
| mean | NaN | 59.93 | 1.43e-01 | 26.19 | 0.88 |
| std | NaN | 12.23 | 2.57e-01 | 35.89 | 0.54 |
| min | NaN | 41.00 | 9.00e-03 | 2.00 | 0.20 |
| 25% | NaN | 49.75 | 2.05e-02 | 3.38 | 0.47 |
| 50% | NaN | 57.50 | 4.35e-02 | 7.70 | 0.75 |
| 75% | NaN | 71.25 | 7.98e-02 | 32.85 | 1.20 |
| max | NaN | 81.00 | 8.16e-01 | 127.00 | 2.10 |
2.3 探索性資料分析(Exploratory Data Analysis, EDA)¶
# 資料列數與行數 (28, 5)
df_ctsi.shape
(28, 5)
# isnull 顯示資料沒有遺漏值 (Missing Values)
df_ctsi.isnull().sum()
itemname sitename 0 卡爾森指數 0 總磷 0 葉綠素a 0 透明度 0 dtype: int64
# 資料型態: 卡爾森指數等測量值已經正確轉換為 float64.
df_ctsi.dtypes
itemname sitename object 卡爾森指數 int64 總磷 float64 葉綠素a float64 透明度 float64 dtype: object
# 顯示前5筆
df_ctsi.head()
| itemname | sitename | 卡爾森指數 | 總磷 | 葉綠素a | 透明度 |
|---|---|---|---|---|---|
| 0 | 七美水庫 | 60 | 5.10e-02 | 16.4 | 0.9 |
| 1 | 南化水庫一 | 41 | 9.00e-03 | 2.0 | 2.1 |
| 2 | 南化水庫三 | 48 | 1.40e-02 | 2.7 | 0.9 |
| 3 | 南化水庫二 | 45 | 1.00e-02 | 2.5 | 1.2 |
| 4 | 寶二水庫一 | 57 | 8.50e-02 | 8.8 | 1.8 |
# 顯示後5筆
df_ctsi.tail()
| itemname | sitename | 卡爾森指數 | 總磷 | 葉綠素a | 透明度 |
|---|---|---|---|---|---|
| 23 | 鏡面水庫二 | 59 | 0.04 | 6.6 | 0.5 |
| 24 | 鳳山水庫一 | 78 | 0.82 | 20.4 | 0.4 |
| 25 | 鳳山水庫三 | 80 | 0.76 | 36.4 | 0.4 |
| 26 | 鳳山水庫二 | 80 | 0.79 | 36.3 | 0.4 |
| 27 | 鳳山水庫四 | 81 | 0.66 | 86.7 | 0.5 |
# 將卡爾森指數資料集(df_ctsi)與經緯度(df_location)資料集合併
df_ctsi = df_ctsi.merge(df_location, on = 'sitename')
df_ctsi
| sitename | 卡爾森指數 | 總磷 | 葉綠素a | 透明度 | twd97lon | twd97lat | |
|---|---|---|---|---|---|---|---|
| 0 | 七美水庫 | 60 | 5.10e-02 | 16.4 | 0.9 | 119.43 | 23.21 |
| 1 | 南化水庫一 | 41 | 9.00e-03 | 2.0 | 2.1 | 120.54 | 23.09 |
| 2 | 南化水庫三 | 48 | 1.40e-02 | 2.7 | 0.9 | 120.56 | 23.13 |
| 3 | 南化水庫二 | 45 | 1.00e-02 | 2.5 | 1.2 | 120.55 | 23.11 |
| 4 | 寶二水庫一 | 57 | 8.50e-02 | 8.8 | 1.8 | 121.04 | 24.72 |
| 5 | 小池水庫 | 59 | 3.70e-02 | 8.8 | 0.5 | 119.51 | 23.61 |
| 6 | 德基水庫五 | 56 | 2.60e-02 | 10.3 | 0.8 | 121.25 | 24.27 |
| 7 | 成功水庫 | 71 | 6.10e-02 | 81.1 | 0.3 | 119.63 | 23.58 |
| 8 | 東衛水庫 | 72 | 7.80e-02 | 75.7 | 0.3 | 119.60 | 23.57 |
| 9 | 湖山水庫一 | 49 | 2.20e-02 | 2.7 | 1.2 | 120.63 | 23.68 |
| 10 | 湖山水庫二 | 52 | 1.90e-02 | 3.3 | 0.6 | 120.63 | 23.68 |
| 11 | 澄清湖水庫一 | 58 | 4.80e-02 | 3.4 | 0.5 | 120.35 | 22.65 |
| 12 | 澄清湖水庫三 | 52 | 2.70e-02 | 3.9 | 1.0 | 120.35 | 22.66 |
| 13 | 澄清湖水庫二 | 52 | 2.80e-02 | 4.7 | 1.1 | 120.35 | 22.66 |
| 14 | 澄清湖水庫四 | 63 | 4.80e-02 | 31.7 | 0.7 | 120.35 | 22.66 |
| 15 | 牡丹水庫一 | 49 | 1.60e-02 | 6.1 | 1.6 | 120.78 | 22.13 |
| 16 | 牡丹水庫三 | 50 | 2.10e-02 | 4.5 | 1.4 | 120.78 | 22.15 |
| 17 | 牡丹水庫二 | 48 | 1.50e-02 | 5.5 | 1.6 | 120.78 | 22.14 |
| 18 | 石門水庫六 | 56 | 8.80e-02 | 2.5 | 1.0 | 121.30 | 24.81 |
| 19 | 興仁水庫 | 74 | 7.80e-02 | 111.0 | 0.3 | 119.61 | 23.55 |
| 20 | 蘭湖水庫 | 77 | 8.60e-02 | 127.0 | 0.2 | 118.38 | 24.45 |
| 21 | 西安水庫 | 45 | 1.60e-02 | 2.7 | 1.9 | 119.50 | 23.36 |
| 22 | 金湖水庫 | 66 | 7.00e-02 | 29.7 | 0.6 | 118.46 | 24.43 |
| 23 | 鏡面水庫二 | 59 | 3.90e-02 | 6.6 | 0.5 | 120.49 | 23.06 |
| 24 | 鳳山水庫一 | 78 | 8.16e-01 | 20.4 | 0.4 | 120.39 | 22.54 |
| 25 | 鳳山水庫三 | 80 | 7.63e-01 | 36.4 | 0.4 | 120.39 | 22.54 |
| 26 | 鳳山水庫二 | 80 | 7.88e-01 | 36.3 | 0.4 | 120.39 | 22.54 |
| 27 | 鳳山水庫四 | 81 | 6.59e-01 | 86.7 | 0.5 | 120.39 | 22.54 |
水庫CTSI卡爾森指數-資料視覺化¶
# 設定地理中心位置的啟始檢視位置
m = folium.Map(location=[23.97565, 120.9738819], zoom_start=8)
for index, row in df_ctsi.iterrows():
# 將資料點使用圓形標記加在地圖上
folium.CircleMarker(
radius=10, # 半徑
location=[row['twd97lat'], row['twd97lon']], # 位置
stroke=False, # 是否顯示框線
fill=True, # 是否填滿
fill_opacity=0.9, # 設定透明度: 1=完全不透明, 0.1=完全透明
popup ="測站: {} \n CTSI卡爾森指數: {}".format(row["sitename"], row["卡爾森指數"]),
tooltip="測站: {} \n CTSI卡爾森指數: {}".format(row["sitename"], row["卡爾森指數"]),
).add_to(m)
# icon list: https://fontawesome.com/icons
# 加入置中標題
titles = '水庫卡爾森指數系統-2025.06.17-@RWPEA'
title_html = '''
<h3 align="center" style="font-size:16px"><b>{}</b></h3>
'''.format(titles)
m.get_root().html.add_child(folium.Element(title_html))
<branca.element.Element at 0x184a18da3f0>
# 繪製地理資料視覺化
m
# end